package com.dts.web.controller.common;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.dts.common.core.domain.AjaxResult;
import com.dts.common.utils.DateUtils;
import com.dts.common.utils.StringUtils;
import com.dts.common.utils.uuid.IdUtils;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.errors.MinioException;

/**
 * MinIO文件操作控制器
 * 
 * @author dts
 */
@RestController
@RequestMapping("/common/minio")
public class MinioController {

    private static final Logger log = LoggerFactory.getLogger(MinioController.class);

    @Autowired
    private MinioClient minioClient;

    @Value("${spring.minio.bucketName}")
    private String bucketName;

    private static final String FILE_DELIMETER = ",";

    /**
     * 上传文件到MinIO（单个）
     */
    @PostMapping("/upload")
    public AjaxResult uploadFile(MultipartFile file) {
        try {
            if (file.isEmpty()) {
                return AjaxResult.error("上传文件不能为空");
            }

            // 检查并创建bucket
            boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!found) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }

            // 生成日期路径（格式：yyyy/MM/dd）
            String datePath = DateUtils.datePath();
            // 生成文件名（使用IdUtils生成随机ID）
            String fileName = datePath + "/" + IdUtils.simpleUUID() + "." + StringUtils.substringAfterLast(file.getOriginalFilename(), ".");
            
            // 上传文件
            try (InputStream inputStream = file.getInputStream()) {
                minioClient.putObject(
                    PutObjectArgs.builder()
                        .bucket(bucketName)
                        .object(fileName)
                        .stream(inputStream, file.getSize(), -1)
                        .contentType(file.getContentType())
                        .build()
                );
            }

            // 获取文件URL（设置7天访问期限）
            String fileUrl = minioClient.getPresignedObjectUrl(
                io.minio.GetPresignedObjectUrlArgs.builder()
                    .method(io.minio.http.Method.GET)
                    .bucket(bucketName)
                    .object(fileName)
                    .expiry(7, TimeUnit.DAYS)
                    .build()
            );
            
            AjaxResult ajax = AjaxResult.success();
            ajax.put("url", fileUrl);
            ajax.put("fileName", fileName);
            ajax.put("originalFilename", file.getOriginalFilename());
            return ajax;
        } catch (MinioException e) {
            log.error("MinIO文件上传失败", e);
            return AjaxResult.error("MinIO文件上传失败: " + e.getMessage());
        } catch (Exception e) {
            log.error("文件上传失败", e);
            return AjaxResult.error("文件上传失败: " + e.getMessage());
        }
    }

    /**
     * 上传文件到MinIO（多个）
     */
    @PostMapping("/uploads")
    public AjaxResult uploadFiles(List<MultipartFile> files) {
        try {
            if (files == null || files.isEmpty()) {
                return AjaxResult.error("上传文件不能为空");
            }
            // 检查并创建bucket
            boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!found) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }

            // 生成日期路径（格式：yyyy/MM/dd）
            String datePath = DateUtils.datePath();
            
            List<String> urls = new ArrayList<>();
            List<String> fileNames = new ArrayList<>();
            List<String> originalFilenames = new ArrayList<>();

            for (MultipartFile file : files) {
                if (file.isEmpty()) {
                    continue;
                }

                // 生成文件名（使用IdUtils生成随机ID，并添加日期路径）
                String fileName = datePath + "/" + IdUtils.simpleUUID() + "." + StringUtils.substringAfterLast(file.getOriginalFilename(), ".");
                
                // 上传文件
                try (InputStream inputStream = file.getInputStream()) {
                    minioClient.putObject(
                        PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(fileName)
                            .stream(inputStream, file.getSize(), -1)
                            .contentType(file.getContentType())
                            .build()
                    );
                }

                // 获取文件URL（设置7天访问期限）
                String fileUrl = minioClient.getPresignedObjectUrl(
                    io.minio.GetPresignedObjectUrlArgs.builder()
                        .method(io.minio.http.Method.GET)
                        .bucket(bucketName)
                        .object(fileName)
                        .expiry(7, TimeUnit.DAYS)
                        .build()
                );
                
                urls.add(fileUrl);
                fileNames.add(fileName);
                originalFilenames.add(file.getOriginalFilename());
            }

            AjaxResult ajax = AjaxResult.success();
            ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER));
            ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER));
            ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER));
            return ajax;
        } catch (MinioException e) {
            log.error("MinIO文件上传失败", e);
            return AjaxResult.error("MinIO文件上传失败: " + e.getMessage());
        } catch (Exception e) {
            log.error("文件上传失败", e);
            return AjaxResult.error("文件上传失败: " + e.getMessage());
        }
    }
}